/**
 * debounce 功能
 * @date 2023/10/2
 */

/**
 * 防抖函数
 *
 * 使用：
 * // 创建
 * const count = debounceRef(0, 300)
 *
 * // 函数中使用
 * const addCount = () => {
 *   count.value += 1
 * }
 *
 * // v-model 中使用
 * <input type="text" v-model="count">
 *
 * @param data 为创建时的数据
 * @param delay 为防抖时间
 */
export function debounceRef<T>(data: T, delay = 300) {
  // 创建定时器
  let timer: any = null;
  // 对 delay 进行判断，如果传递的是 null 则不需要使用 防抖方案，直接返回使用 ref 创建的。
  return delay == null
    ? // 返回 ref 创建的
      ref<T>(data)
    : // customRef 中会返回两个函数参数。一个是：track 在获取数据时收集依赖的；一个是：trigger 在修改数据时进行通知派发更新的。
      customRef<T>((track, trigger) => {
        return {
          get() {
            // 收集依赖
            track();
            // 返回当前数据的值
            return data;
          },
          set(value) {
            // 清除定时器
            if (timer != null) {
              clearTimeout(timer);
              timer = null;
            }
            // 创建定时器
            timer = setTimeout(() => {
              // 修改数据
              data = value;
              // 派发更新
              trigger();
            }, delay);
          },
        };
      });
}
